package com.coldworks.coldjoke.ui;

import java.io.File;
import java.io.FileInputStream;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.coldworks.base.manager.BaseBitmapManager;
import com.coldworks.base.manager.BaseDisplayManager;
import com.coldworks.base.manager.BaseStorageManager;
import com.coldworks.coldjoke.R;
import com.coldworks.coldjoke.activity.ViewImageActivity;
import com.coldworks.coldjoke.adapter.ReplyAdapter;
import com.coldworks.coldjoke.manager.JokeDbManager;
import com.coldworks.coldjoke.model.JokeEntity;
import com.coldworks.coldjoke.model.JokeModel;
import com.coldworks.coldjoke.model.ReplyModel;
import com.coldworks.coldjoke.task.AsyncImgLoader;
import com.coldworks.coldjoke.task.AsyncImgLoader.FileImageCallback;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.util.AttributeSet;
import android.util.Base64;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.view.animation.Animation.AnimationListener;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class JokePageCell extends ListView {
	protected final Logger log = LoggerFactory.getLogger(this.getClass());
	// 显示数据
	private Context context;
	private JokePageCellDelegate delegate;
	private JokeEntity jokeEntity;
	private JokeModel jokeModel;
	private List<ReplyModel> list;
	private ReplyAdapter replyAdapter;
	private Bitmap bitmap;

	private RelativeLayout mainView;
	private TextView jokeContent;
	private ImageView jokeImage;
	private TextView jokeUserName;
	private TextView jokeLikeNum;
	private TextView jokeDislikeNum;
	private RelativeLayout goodBtn;
	private RelativeLayout badBtn;
	private TextView jokeLikeAnim;
	private TextView jokeDislikeAnim;
	private ImageView goodImg;
	private ImageView badImg;
	private TextView jokeReplyNum;
	private ProgressBar replyProgress;
	private WebView jokeWebView;

	private int[] location = new int[2];

	public JokePageCell(Context context) {
		super(context);
		setUpViews(context);
	}

	public JokePageCell(Context context, AttributeSet attrs) {
		super(context, attrs);
		setUpViews(context);
	}

	public JokePageCell(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		setUpViews(context);
	}

	private void setUpViews(final Context context) {
		this.context = context;
		mainView = (RelativeLayout) LayoutInflater.from(context).inflate(
				R.layout.navigation_joke_page_cell, null);
		jokeWebView = (WebView) mainView.findViewById(R.id.gif_webview);
		jokeContent = (TextView) mainView.findViewById(R.id.joke_content);
		jokeLikeNum = (TextView) mainView.findViewById(R.id.joke_like_num);
		jokeDislikeNum = (TextView) mainView
				.findViewById(R.id.joke_dislike_num);
		goodBtn = (RelativeLayout) mainView.findViewById(R.id.button_good);
		badBtn = (RelativeLayout) mainView.findViewById(R.id.button_bad);
		jokeLikeAnim = (TextView) mainView.findViewById(R.id.joke_like_anim);
		jokeDislikeAnim = (TextView) mainView
				.findViewById(R.id.joke_dislike_anim);
		goodImg = (ImageView) mainView.findViewById(R.id.good_img);
		badImg = (ImageView) mainView.findViewById(R.id.bad_img);
		jokeUserName = (TextView) mainView.findViewById(R.id.joke_user);
		jokeImage = (ImageView) mainView.findViewById(R.id.joke_image);
		jokeReplyNum = (TextView) mainView.findViewById(R.id.joke_reply_num);
		replyProgress = (ProgressBar) mainView
				.findViewById(R.id.joke_reply_progress);
		addHeaderView(mainView);
		LinearLayout empty = (LinearLayout) LayoutInflater.from(context)
				.inflate(R.layout.navigation_joke_reply_footer, null);
		addFooterView(empty);
		setDividerHeight(5);
		setCacheColorHint(getResources().getColor(R.color.transparent));
		setDivider(null);
		setSelector(R.color.transparent);
		setFocusableInTouchMode(false);
		setFocusable(false);
		setBackgroundColor(getResources().getColor(R.color.page_bg));
		goodBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				userState.JPCUSlike();
			}
		});
		badBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				userState.JPCUSdislike();
			}
		});
	}

	private Click click = new Click();

	class Click {
		private int x1;
		private int x2;
		private int y1;
		private int y2;
		private boolean started;

		public Click() {
			x1 = 0;
			y1 = 0;
			x2 = 0;
			y2 = 0;
			started = false;
		}

		public void start(MotionEvent event) {
			x1 = (int) event.getX();
			y1 = (int) event.getY();
			x2 = x1;
			y2 = y1;
			started = true;
			// log.info("x=" + x1 + " y=" + y1);
		}

		public void stop(MotionEvent event) {
			if (!started) {
				return;
			}
			started = false;
			x2 = (int) event.getX();
			y2 = (int) event.getY();
			int distX = x2 - x1;
			int distY = y2 - y1;
			int dx = Math.abs(distX);
			int dy = Math.abs(distY);
			float limitX = BaseDisplayManager.getInstance().getDisplayWidth(
					context);
			// float limitY = BaseDisplayManager.getInstance().getDisplayHeight(
			// context);
			// log.info("from (" + x1 + "," + y1 + ") to (" + x2 + "," + y2
			// + ") moved:(" + distX + "," + distY + ") in screen("
			// + limitX + "," + limitY + ")");
			if (dy > dx) {
				// log.info("fling " + (distY > 0 ? "down" : "up"));
				return;
			}
			// 手指划过四分之一的屏幕才可以翻页
			if (distX < -(limitX / 4)) {
				// log.info("fling left");
				if (delegate != null) {
					delegate.JPCleft();
				}
			} else if (distX > limitX / 4) {
				// log.info("fling right");
				if (delegate != null) {
					delegate.JPCright();
				}
			}
		}
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		int action = ev.getAction();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			// log.info("ACTION_DOWN");
			click.start(ev);
			break;
		case MotionEvent.ACTION_MOVE:
			// log.info("ACTION_MOVE");
			break;
		case MotionEvent.ACTION_UP:
			// log.info("ACTION_UP");
			click.stop(ev);
			break;
		case MotionEvent.ACTION_CANCEL:
			// log.info("ACTION_CANCEL");
			break;
		}
		return super.onInterceptTouchEvent(ev);
	}

	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			// log.info("ACTION_DOWN");
			break;
		case MotionEvent.ACTION_MOVE:
			// log.info("ACTION_MOVE");
			break;
		case MotionEvent.ACTION_UP:
			// log.info("ACTION_UP");
			click.stop(ev);
			break;
		case MotionEvent.ACTION_CANCEL:
			// log.info("ACTION_CANCEL");
			break;
		}
		return super.onTouchEvent(ev);
	}

	// 每次展示新的JokeModel时都要启动Loading
	public void setJokeModel(JokePageCellDelegate pDelegate,
			JokeEntity pJokeEntity, JokeModel pJokeModel) {
		this.delegate = pDelegate;
		this.jokeEntity = pJokeEntity;
		this.jokeModel = pJokeModel;

		this.setLikeState(likeStateLoading);
		if (jokeModel == null) {
			jokeContent.setText("");
			jokeReplyNum.setText("");
			jokeLikeNum.setText("");
			jokeDislikeNum.setText("");
			jokeUserName.setText("");
			jokeImage.setVisibility(View.GONE);
			jokeWebView.setVisibility(View.GONE);
			return;
		}
		jokeContent.setText(jokeModel.getJokeText());
		jokeLikeNum.setText("+" + String.valueOf(jokeModel.getGoodNum()));
		jokeDislikeNum.setText("-" + String.valueOf(jokeModel.getBadNum()));
		jokeUserName.setText(jokeModel.getUserName());

		if (!jokeModel.getImgUrl().equals("")) {
			jokeImage.setImageDrawable(context.getResources().getDrawable(
					R.drawable.ic_photo));
			jokeImage.setVisibility(View.VISIBLE);
			jokeWebView.setVisibility(View.GONE);

			if (BaseBitmapManager.getInstance().fileIsGIF(
					jokeModel.getImgPath())) {
				WebSettings webset = jokeWebView.getSettings();
				webset.setLoadWithOverviewMode(true);
				webset.setAllowFileAccess(true);
				webset.setLoadsImagesAutomatically(true);
				String gifHtml = "<html><head></head><body>"
						// + "<img src='data:image/gif;base64," +
						// gifData
						+ "<img src='file://" + jokeModel.getImgPath()
						+ "' /></body></html>";
				log.info(gifHtml);
				jokeWebView.loadDataWithBaseURL(null, gifHtml, "text/html",
						"utf-8", null);
				// jokeWebView.loadDataWithBaseURL("about:blank",
				// UrlUtil.getShowGifHtml(jokeModel.getImgUrl()),
				// "text/html", "utf-8", null);
				jokeImage.setVisibility(View.GONE);
				jokeWebView.setVisibility(View.VISIBLE);
			} else {
				log.info("loading img file : " + jokeModel.getImgPath());
				bitmap = AsyncImgLoader.getInstance().loadDrawableByPath(
						context, jokeModel.getImgPath(), jokeImage,
						new FileImageCallback() {
							@Override
							public void imageLoaded(Bitmap imageDrawable,
									ImageView imageView, String imagePath) {
								log.info("img loaded");
								if (!jokeModel.getImgPath().equals(imagePath)) {
									log.info("cell changed");
									return;
								}
								imageView.setImageBitmap(imageDrawable);
								imageView
										.setOnClickListener(new OnClickListener() {
											@Override
											public void onClick(View v) {
												Intent intent = null;
												String imgPath = jokeModel
														.getImgPath();
												// if (BaseBitmapManager
												// .getInstance().isGIF(
												// imgPath)) {
												// // 可进行gif的展示和保存，但是目前没有必要
												// } else {
												intent = new Intent(context,
														ViewImageActivity.class);
												// }
												log.info(imgPath);
												intent.putExtra("imgPath",
														imgPath);
												context.startActivity(intent);
											}
										});
							}
						}, false);
				if (bitmap != null) {
					jokeImage.setImageBitmap(bitmap);
				} else {
					log.info("load null from cache");
				}
			}
		} else {
			jokeImage.setVisibility(View.GONE);
			jokeWebView.setVisibility(View.GONE);
		}

		replyProgress.setVisibility(JokePageCell.GONE);
		list = jokeModel.getReplyInfoList();
		if (list.isEmpty()) {
			jokeReplyNum.setText("正在加载评论...");
		} else {
			jokeReplyNum.setText("正在刷新评论...");
		}
		replyAdapter = new ReplyAdapter(context, list);
		setAdapter(replyAdapter);
	}

	public void setBgVisible(boolean visible) {
		if (visible) {
			mainView.setBackgroundColor(context.getResources().getColor(
					R.color.page_bg));
		} else {
			mainView.setBackgroundColor(context.getResources().getColor(
					R.color.transparent));
		}
	}

	public String encodeBase64File(String path) throws Exception {
		File file = new File(path);
		FileInputStream inputFile = new FileInputStream(file);
		byte[] buffer = new byte[(int) file.length()];
		inputFile.read(buffer);
		inputFile.close();
		return android.util.Base64.encodeToString(buffer, Base64.DEFAULT);
	}

	public JokeModel getJokeModel() {
		return jokeModel;
	}

	// 获取新的评论后要重新填入Listview，并隐藏loading
	public void refreshReply() {
		list = jokeModel.getReplyInfoList();
		replyAdapter = new ReplyAdapter(context, list);
		setAdapter(replyAdapter);
		replyProgress.setVisibility(JokePageCell.GONE);
		jokeReplyNum.setText(list.size() + "条评论");
	}

	public void setReplyNew(ReplyModel replyInfo) {
		this.list.add(replyInfo);
		replyAdapter.notifyDataSetChanged();
	}

	// 回收图片
	public void recycle() {
		jokeImage.setImageBitmap(null);
		if ((this.bitmap == null) || (this.bitmap.isRecycled()))
			return;
		this.bitmap.recycle();
		this.bitmap = null;
	}

	/**
	 * 在ListView中捕捉到左滑和右滑事件，有需要的可回调。
	 * 
	 */
	public interface JokePageCellDelegate {
		void JPCleft();

		void JPCright();

		void JPClogin();

		void JPCvote(String itemType);
	}

	public void setLikeState(JPCLikeStateBase newState) {
		likeState = newState;
		likeState.JPCLSstart();
	}

	public void setUserState(JPCUserStateBase newState) {
		userState = newState;
	}

	private JPCLikeStateBase likeState;
	public JPCLikeStateLoading likeStateLoading = new JPCLikeStateLoading();
	public JPCLikeStateEnable likeStateEnable = new JPCLikeStateEnable();
	public JPCLikeStateDisable likeStateDisable = new JPCLikeStateDisable();

	public abstract class JPCLikeStateBase {
		public void JPCLSstart() {

			if (jokeModel.getLiked() == 1) {
				goodImg.setImageDrawable(context.getResources().getDrawable(
						R.drawable.action_good_2));
				badImg.setImageDrawable(context.getResources().getDrawable(
						R.drawable.action_bad_1));
			} else if (jokeModel.getDisliked() == 1) {
				goodImg.setImageDrawable(context.getResources().getDrawable(
						R.drawable.action_good_1));
				badImg.setImageDrawable(context.getResources().getDrawable(
						R.drawable.action_bad_2));
			} else {
				goodImg.setImageDrawable(context.getResources().getDrawable(
						R.drawable.action_good_1));
				badImg.setImageDrawable(context.getResources().getDrawable(
						R.drawable.action_bad_1));
			}

			// goodImg.setImageDrawable(context.getResources().getDrawable(
			// jokeModel.getLiked() == 1 ? R.drawable.action_good_2
			// : R.drawable.action_good_1));
			// badImg.setImageDrawable(context.getResources().getDrawable(
			// jokeModel.getLiked() == 1 ? R.drawable.action_bad_2
			// : R.drawable.action_bad_1));
		}

		public abstract void JPCLSlike();

		public abstract void JPCLSdislike();
	}

	public class JPCLikeStateLoading extends JPCLikeStateBase {
		public void JPCLSstart() {
			goodImg.setImageDrawable(context.getResources().getDrawable(
					R.drawable.action_good_3));
			badImg.setImageDrawable(context.getResources().getDrawable(
					R.drawable.action_bad_3));
		}

		public void JPCLSlike() {
			Toast.makeText(context, "正在加载,请稍候...", Toast.LENGTH_SHORT).show();
		}

		public void JPCLSdislike() {
			Toast.makeText(context, "正在加载,请稍候...", Toast.LENGTH_SHORT).show();
		}
	}

	public class JPCLikeStateEnable extends JPCLikeStateBase {

		public void JPCLSlike() {
			jokeModel.setLiked(1);
			jokeModel.setDisliked(0);
			jokeModel.setGoodNum(jokeModel.getGoodNum() + 1);
			jokeLikeNum.setText("+" + String.valueOf(jokeModel.getGoodNum()));
			jokeDislikeNum.setText("-" + String.valueOf(jokeModel.getBadNum()));
			goodImg.setImageDrawable(context.getResources().getDrawable(
					R.drawable.action_good_2));
			badImg.setImageDrawable(context.getResources().getDrawable(
					R.drawable.action_bad_1));
			delegate.JPCvote("like_joke");
			setLikeState(likeStateDisable);
			JokeDbManager.getInstance().updateOneJoke(context,
					jokeEntity.manager.getJokesSort(), jokeModel);

			int[] location = new int[2];
			goodBtn.getLocationInWindow(location);
			showGoodTip();

		}

		public void JPCLSdislike() {
			jokeModel.setLiked(0);
			jokeModel.setDisliked(1);
			jokeModel.setBadNum(jokeModel.getBadNum() + 1);
			jokeLikeNum.setText("+" + String.valueOf(jokeModel.getGoodNum()));
			jokeDislikeNum.setText("-" + String.valueOf(jokeModel.getBadNum()));
			goodImg.setImageDrawable(context.getResources().getDrawable(
					R.drawable.action_good_1));
			badImg.setImageDrawable(context.getResources().getDrawable(
					R.drawable.action_bad_2));
			delegate.JPCvote("unlike_joke");
			setLikeState(likeStateDisable);
			JokeDbManager.getInstance().updateOneJoke(context,
					jokeEntity.manager.getJokesSort(), jokeModel);
			badBtn.getLocationInWindow(location);
			showBadTip();
		}
	}

	public class JPCLikeStateDisable extends JPCLikeStateBase {

		public void JPCLSlike() {
			if (jokeModel.getLiked() == 1 && jokeModel.getDisliked() == 0) {
				Toast.makeText(context, "你已经顶过啦！", Toast.LENGTH_SHORT).show();
			} else if (jokeModel.getDisliked() == 1) {
				jokeModel.setLiked(1);
				jokeModel.setDisliked(0);
				jokeModel.setBadNum(jokeModel.getBadNum() - 1);
				jokeModel.setGoodNum(jokeModel.getGoodNum() + 1);
				jokeLikeNum.setText("+"
						+ String.valueOf(jokeModel.getGoodNum()));
				jokeDislikeNum.setText("-"
						+ String.valueOf(jokeModel.getBadNum()));
				goodImg.setImageDrawable(context.getResources().getDrawable(
						R.drawable.action_good_2));
				badImg.setImageDrawable(context.getResources().getDrawable(
						R.drawable.action_bad_1));
				// delegate.JPCvote("unlike_joke");
				// setLikeState(likeStateDisable);
				JokeDbManager.getInstance().updateOneJoke(context,
						jokeEntity.manager.getJokesSort(), jokeModel);

				// int[] location = new int[2];
				goodBtn.getLocationInWindow(location);
				showGoodTip();
			}
		}

		public void JPCLSdislike() {
			if (jokeModel.getLiked() == 1 && jokeModel.getDisliked() == 0) {
				jokeModel.setLiked(0);
				jokeModel.setDisliked(1);
				jokeModel.setGoodNum(jokeModel.getGoodNum() - 1);
				jokeModel.setBadNum(jokeModel.getBadNum() + 1);
				jokeLikeNum.setText("+"
						+ String.valueOf(jokeModel.getGoodNum()));
				jokeDislikeNum.setText("-"
						+ String.valueOf(jokeModel.getBadNum()));
				goodImg.setImageDrawable(context.getResources().getDrawable(
						R.drawable.action_good_1));
				badImg.setImageDrawable(context.getResources().getDrawable(
						R.drawable.action_bad_2));
				// delegate.JPCvote("like_joke");
				// setLikeState(likeStateDisable);
				JokeDbManager.getInstance().updateOneJoke(context,
						jokeEntity.manager.getJokesSort(), jokeModel);
				badBtn.getLocationInWindow(location);
				showBadTip();
			} else if (jokeModel.getDisliked() == 1) {
				Toast.makeText(context, "你已经踩过啦！", Toast.LENGTH_SHORT).show();
			}
		}
	}

	public abstract class JPCUserStateBase {

		public abstract void JPCUSlike();

		public abstract void JPCUSdislike();
	}

	private JPCUserStateBase userState;
	public JPCUserStateLogin userStateLogin = new JPCUserStateLogin();
	public JPCUserStateLogout userStateLogout = new JPCUserStateLogout();

	public class JPCUserStateLogin extends JPCUserStateBase {
		public void JPCUSlike() {
			if (likeState != null) {
				likeState.JPCLSlike();
			}
		}

		public void JPCUSdislike() {
			if (likeState != null) {
				likeState.JPCLSdislike();
			}
		}
	}

	public class JPCUserStateLogout extends JPCUserStateBase {
		public void JPCUSlike() {
			if (delegate != null) {
				delegate.JPClogin();
			}
		}

		public void JPCUSdislike() {
			if (delegate != null) {
				delegate.JPClogin();
			}
		}
	}

	private void showGoodTip() {
		invalidate();
		final AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
		alphaAnimation.setDuration(500);
		final ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 3.0f,
				1.0f, 3.0f);
		scaleAnimation.setDuration(500);
		scaleAnimation.setAnimationListener(new AnimationListener() {
			@Override
			public void onAnimationStart(Animation animation) {
				jokeLikeAnim.setVisibility(TextView.VISIBLE);
			}

			@Override
			public void onAnimationRepeat(Animation animation) {
			}

			@Override
			public void onAnimationEnd(Animation animation) {
				jokeLikeAnim.setVisibility(TextView.GONE);
				invalidate();
			}
		});
		final TranslateAnimation translateAnimation = new TranslateAnimation(0,
				-8, 0, -30);
		translateAnimation.setDuration(500);
		AnimationSet set = new AnimationSet(true);
		set.addAnimation(alphaAnimation);
		set.addAnimation(translateAnimation);
		set.addAnimation(scaleAnimation);
		jokeLikeAnim.startAnimation(set);

	}

	private void showBadTip() {
		invalidate();
		final AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
		alphaAnimation.setDuration(500);
		final ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 3.0f,
				1.0f, 3.0f);
		scaleAnimation.setDuration(500);
		scaleAnimation.setAnimationListener(new AnimationListener() {
			@Override
			public void onAnimationStart(Animation animation) {
				jokeDislikeAnim.setVisibility(TextView.VISIBLE);
			}

			@Override
			public void onAnimationRepeat(Animation animation) {
			}

			@Override
			public void onAnimationEnd(Animation animation) {
				jokeDislikeAnim.setVisibility(TextView.GONE);
				invalidate();
			}
		});
		final TranslateAnimation translateAnimation = new TranslateAnimation(0,
				-8, 0, -30);
		translateAnimation.setDuration(500);
		AnimationSet set = new AnimationSet(true);
		set.addAnimation(alphaAnimation);
		set.addAnimation(translateAnimation);
		set.addAnimation(scaleAnimation);
		jokeDislikeAnim.startAnimation(set);
	}
}
